package org.apli.haiam.controladores;

import com.apli.controladores.Aplinfo;
import com.apli.ejb.controladores.AbstractFacade;
import com.apli.ejb.exceptions.ApliException;
import com.apli.ejb.exceptions.TipoMensajeError;
import com.lowagie.text.pdf.PdfWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.ejb.Stateless;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.naming.InitialContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JExcelApiExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRPdfExporterParameter;
import net.sf.jasperreports.engine.export.JRRtfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import org.apli.haiam.admin.entidades.ParametrosReporte;
import org.apli.haiam.admin.entidades.UsuarioAdmin;
import org.apli.haiam.ejb.entidades.AdmAuditoria;
import org.apli.haiam.ejb.entidades.CexAgenda;
import org.apli.haiam.ejb.entidades.CexAntecedentesFamiliares;
import org.apli.haiam.ejb.entidades.CexAntecedentesPatologicos;
import org.apli.haiam.ejb.entidades.CexConsulta;
import org.apli.haiam.ejb.entidades.CexConsultaTerapia;
import org.apli.haiam.ejb.entidades.CexDiagnosticoConsulta;
import org.apli.haiam.ejb.entidades.CexExamenFisico;
import org.apli.haiam.ejb.entidades.CexGeriatricoConsulta;
import org.apli.haiam.ejb.entidades.CexHorario;
import org.apli.haiam.ejb.entidades.CexHorariosDia;
import org.apli.haiam.ejb.entidades.CexPedidoLaboratorio;
import org.apli.haiam.ejb.entidades.CexPreparacion;
import org.apli.haiam.ejb.entidades.CexRevisionOrganos;
import org.apli.haiam.ejb.entidades.CexTratamientoConsulta;
import org.apli.haiam.ejb.interfaces.ConsExternaAdministrador;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * clase Abstracta que implementa los métodos que administran los registros de
 * las tablas asociadas a las clases de entidad (EJB3).
 * <p>
 * Implementa en sus meétodos la auditoría.
 * <p>
 * <H6>Soporte:HAIAM
 * <I>david_s_1086@hotmail.com,david.carranza@haiam.gob.ec</I></H6>
 *
 * @author david Carranza
 * @version 1.0 30/07/2014
 * @param <T>
 */
@Stateless
public class ConsExternaAdministradorBean<T> extends AbstractFacade<Object> implements ConsExternaAdministrador {

    /**
     * Variable para registrar sucesos del sistema
     */
    private static final Logger log = LoggerFactory.getLogger(ConsExternaAdministradorBean.class);
    @PersistenceContext(unitName = "Admin-ejbPU")
    private EntityManager em;
    private String path;
    private String pathImages;

    PrintWriter matriz = null;

    //@Resource(name = "jdbc/SigemDS")
    private DataSource ds;

    @Override
    public EntityManager getEntityManager() {
        return em;
    }
    private static final String CREAR_TURNO = "Crear turno";
    private static final String REAGENDAR_TURNO = "Reagendar turno";
    private static final String CREAR_TERAPIA = "Crear terapia";
    private static final String CREAR_HORARIO = "Crear horario";
    private static final String CREAR_LISTA_GERIATRICO = "Crear lista geriatrica";
    private static final String MODIFICAR_LISTA_GERIATRICA = "modificar lista geriatrica";
    private static final String CREAR_LISTA_REVISION_ORGANOS = "Crear lista revision organos";
    private static final String MODIFICAR_LISTA_REVISION_ORGANOS = "modificar lista revision organos";
    private static final String CREAR_LISTA_ANTECEDENTES_PERSONALES = "Crear lista antecedentes personales";
    private static final String MODIFICAR_LISTA_ANTECEDENTES_PERSONALES = "modificar lista antecedentes personales";
    private static final String CREAR_LISTA_ANTECEDENTES_FAMILIARES = "Crear lista antecedentes familiares";
    private static final String MODIFICAR_LISTA_ANTECEDENTES_FAMILIARES = "modificar lista antecedentes familiares";
    private static final String CREAR_LISTA_FISICO_REGIONAL = "Crear lista fisico regional";
    private static final String MODIFICAR_LISTA_FISICO_REGIONAL = "modificar lista fisico regional";
    private static final String CREAR_LISTA_DIAGNOSTICO = "Crear lista diagnostico";
    private static final String CONCLUIR_CONSULTA_AGENDA = "Concluir consulta agenda";
    private static final String CONCLUIR_CONSULTA_PREPARACION = "Concluir consulta preparacion";
    private static final String CONCLUIR_CONSULTA = "Concluir consulta";
    private static final String MODIFICAR_LISTA_DIAGNOSTICO = "modificar lista diagnostico";
    private static final String CREAR_LISTA_CONSULTA_TRATAMIENTO = "Crear lista consulta tratamiento";
    private static final String MODIFICAR_LISTA_CONSULTA_TRATAMIENTO = "modificar lista consulta tratamiento";
    private static final String CREAR = "crear";
    private static final String MODIFICAR = "modificar";
    private static final String CREAR_CONSULTA = "crear consulta";
    private static final String CREAR_PEDIDO_LABORATORIO = "crear pedido laboratorio";
    private static final String MODIFICAR_PEDIDO_LABORATORIO = "modificar pedido laboratorio";
    private static final String CREAR_CONSULTA_TERAPIA = "crear consulta terapia";
    private static final String CANCELAR_CONSULTA_TERAPIA = "cancelar consulta terapia";
    private static final String MODIFICAR_CONSULTA = "modificar consulta";
    private static final String MODIFICAR_HORARIO = "Modificar horario";
    private static final String MODIFICAR_LISTAS = "modificar listas";
    private static final String CANCELAR_TURNO = "Cancelar turno";

    /**
     * Modifica un registro en la tabla asociada a la clase de entidad (EJB3).
     *
     * @param entity la entidad a crear
     * @param user el usuario que modifica la entidad
     * @throws Exception si existe un error
     */
    @Override
    public void crearTurno(Object entity, Object user) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + entity.getClass().getSimpleName() + "," + user.getClass().getSimpleName() + ")";
        UsuarioAdmin user1 = (UsuarioAdmin) user;
        try {
            validarUsuarioSistema(user1);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw e;
        }
        if (user1.getUser().getIdUsuario() != -1 && user1.getPermisosMap().get("modificar" + entity.getClass().getSimpleName()) == null) {
            log.error("{}: No tiene permisos para la acción: {} un elemento de {} [PERMISO:{}]", new Object[]{nombreMetodo, "modificar", entity.getClass().getSimpleName(), "modificar" + entity.getClass().getSimpleName()});
            throw new ApliException(TipoMensajeError.USER_NO_AUTORIZADO);
        }
        try {

            //En el caso de ser un turno para estadistica
            if (entity instanceof CexAgenda) {
                /**
                 * grabar Auditoría
                 */
                String valorDocumento;
                String codigoDocumento;
                String numeroDocumento;
                Integer idDocumento;

                CexAgenda clase = (CexAgenda) entity;
                Object logObj = Aplinfo.cloneObjectEjb(entity, false);
                valorDocumento = clase.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getAdmMedico().getAmeNombreFull();
                numeroDocumento = clase.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getCexEspecialidad().getCesNombre();
                String descripcion = "El usuario " + user1.getNombreFull() + " creo el turno " + clase.getCagSecuencia() + " a la historia clinica " + clase.getCexHistoriaClinica().getChcHistoriaClinica() + " con el médico " + valorDocumento + " en la especialidad" + clase.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getCexEspecialidad().getCesNombre();
                idDocumento = clase.getCagId();
                codigoDocumento = clase.getCexHistoriaClinica().getChcHistoriaClinica();
                grabarAuditoria(CREAR_TURNO, logObj, user1, descripcion, numeroDocumento, codigoDocumento, valorDocumento, idDocumento);
                /**
                 * FIN -- grabar Auditoría
                 */
                getEntityManager().merge(entity);
                return;
            }

            //En el casod e ser un turno para terapia fisica
            if (entity instanceof CexConsultaTerapia) {
                /**
                 * grabar Auditoría
                 */
                String valorDocumento;
                String codigoDocumento;
                Integer idDocumento;

                CexConsultaTerapia clase = (CexConsultaTerapia) entity;
                Object logObj = Aplinfo.cloneObjectEjb(entity, false);
                String descripcion = "El usuario " + user1.getNombreFull() + " creo una terapia " + clase.getCctId() + " a la historia clinica " + clase.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                idDocumento = clase.getCctId();
                codigoDocumento = clase.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                valorDocumento = clase.getCexTipoTerapia().getCttNombre();
                grabarAuditoria(CREAR_TERAPIA, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                /**
                 * FIN -- grabar Auditoría
                 */
                getEntityManager().merge(entity);

            }

        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_MODIFICAR, e);
        }
    }

    /**
     * Modifica un registro en la tabla asociada a la clase de entidad (EJB3).
     *
     * @param entity la entidad a crear
     * @param user el usuario que modifica la entidad
     * @throws Exception si existe un error
     */
    @Override
    public void reagendarTurno(Object entity, Object user) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + entity.getClass().getSimpleName() + "," + user.getClass().getSimpleName() + ")";
        UsuarioAdmin user1 = (UsuarioAdmin) user;
        try {
            validarUsuarioSistema(user1);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw e;
        }
        if (user1.getUser().getIdUsuario() != -1 && user1.getPermisosMap().get("modificar" + entity.getClass().getSimpleName()) == null) {
            log.error("{}: No tiene permisos para la acción: {} un elemento de {} [PERMISO:{}]", new Object[]{nombreMetodo, "modificar", entity.getClass().getSimpleName(), "modificar" + entity.getClass().getSimpleName()});
            throw new ApliException(TipoMensajeError.USER_NO_AUTORIZADO);
        }
        try {

            //En el caso de ser un turno para estadistica
            /**
             * grabar Auditoría
             */
            String valorDocumento;
            String codigoDocumento;
            String numeroDocumento;
            Integer idDocumento;

            CexAgenda clase = (CexAgenda) entity;
            Object logObj = Aplinfo.cloneObjectEjb(entity, false);
            valorDocumento = clase.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getAdmMedico().getAmeNombreFull();
            numeroDocumento = clase.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getCexEspecialidad().getCesNombre();
            String descripcion = "El usuario " + user1.getNombreFull() + " reagendo el turno " + clase.getCagSecuencia() + " a la historia clinica " + clase.getCexHistoriaClinica().getChcHistoriaClinica() + " con el médico " + valorDocumento + " en la especialidad" + clase.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getCexEspecialidad().getCesNombre();
            idDocumento = clase.getCagId();
            codigoDocumento = clase.getCexHistoriaClinica().getChcHistoriaClinica();
            grabarAuditoria(REAGENDAR_TURNO, logObj, user1, descripcion, numeroDocumento, codigoDocumento, valorDocumento, idDocumento);
            /**
             * FIN -- grabar Auditoría
             */
            getEntityManager().merge(entity);

        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_MODIFICAR, e);
        }
    }

    /**
     * Modifica un registro en la tabla asociada a la clase de entidad (EJB3).
     *
     * @param entity la entidad a crear
     * @param user el usuario que modifica la entidad
     * @throws Exception si existe un error
     */
    @Override
    public void concluirConsulta(Object entity, Object user) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + entity.getClass().getSimpleName() + "," + user.getClass().getSimpleName() + ")";
        UsuarioAdmin user1 = (UsuarioAdmin) user;
        try {
            validarUsuarioSistema(user1);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw e;
        }
        if (user1.getUser().getIdUsuario() != -1 && user1.getPermisosMap().get("modificar" + entity.getClass().getSimpleName()) == null) {
            log.error("{}: No tiene permisos para la acción: {} un elemento de {} [PERMISO:{}]", new Object[]{nombreMetodo, "modificar", entity.getClass().getSimpleName(), "modificar" + entity.getClass().getSimpleName()});
            throw new ApliException(TipoMensajeError.USER_NO_AUTORIZADO);
        }
        try {
            /**
             * grabar Auditoría
             */
            String valorDocumento;
            String codigoDocumento;
            Integer idDocumento;
            String numeroDocumento;

            //Actualizacion de agenda
            CexConsulta clase = (CexConsulta) entity;
            CexAgenda agenda = clase.getCexPreparacion().getCexAgenda();
            agenda.setCagEstado(3);
            Object logObj = Aplinfo.cloneObjectEjb(agenda, false);
            String descripcion = "El usuario " + user1.getNombreFull() + " cambio de estado el turno " + agenda.getCagSecuencia() + " a la historia clinica " + agenda.getCexHistoriaClinica().getChcHistoriaClinica() + " por concluir una atencion";
            idDocumento = agenda.getCagId();
            codigoDocumento = agenda.getCexHistoriaClinica().getChcHistoriaClinica();
            numeroDocumento = Integer.toString(clase.getCcoId());
            valorDocumento = "Consulta";
            grabarAuditoria(CONCLUIR_CONSULTA_AGENDA, logObj, user1, descripcion, numeroDocumento, codigoDocumento, valorDocumento, idDocumento);
            /**
             * FIN -- grabar Auditoría
             */
            getEntityManager().merge(agenda);

            //Actualizacion de Preparacion
            CexPreparacion preparacion = clase.getCexPreparacion();
            preparacion.setCprEstado(2);
            /**
             * grabar Auditoría
             */
            Object logObj2 = Aplinfo.cloneObjectEjb(preparacion, false);
            String descripcion2 = "El usuario " + user1.getNombreFull() + " cambio de estado de la preparacion " + preparacion.getCprId() + " a la historia clinica " + preparacion.getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica() + " por concluir una atencion";
            idDocumento = preparacion.getCprId();
            codigoDocumento = preparacion.getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
            numeroDocumento = Integer.toString(clase.getCcoId());
            valorDocumento = "Consulta";
            grabarAuditoria(CONCLUIR_CONSULTA_PREPARACION, logObj2, user1, descripcion2, numeroDocumento, codigoDocumento, valorDocumento, idDocumento);
            /**
             * FIN -- grabar Auditoría
             */
            getEntityManager().merge(preparacion);

            //Actualizacion de consulta
            Object logObj3 = Aplinfo.cloneObjectEjb(entity, false);
            String descripcion3 = "El usuario " + user1.getNombreFull() + " cambio estado de consulta " + clase.getCcoId() + " a la historia clinica " + clase.getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
            idDocumento = clase.getCcoId();
            codigoDocumento = clase.getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
            valorDocumento = clase.getCexPreparacion().getCexAgenda().getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getAdmMedico().getAmeNombreFull();
            numeroDocumento = clase.getCexPreparacion().getCexAgenda().getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getCexEspecialidad().getCesNombre();
            grabarAuditoria(CONCLUIR_CONSULTA, logObj3, user1, descripcion3, numeroDocumento, codigoDocumento, valorDocumento, idDocumento);
            /**
             * FIN -- grabar Auditoría
             */
            getEntityManager().merge(entity);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_MODIFICAR, e);
        }
    }

    /**
     * Crea un registro en la tabla asociada a la clase de entidad (EJB3).
     *
     * @param entity la entidad a crear
     * @param user el usuario que crea la entidad
     * @throws Exception si existe un error
     */
    @Override
    public void crearMaestroDetalle(Object entity, Object user) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + entity.getClass().getSimpleName() + "," + user.getClass().getSimpleName() + ")";
        UsuarioAdmin user1 = (UsuarioAdmin) user;
        try {
            validarUsuarioSistema(user1);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw e;
        }
        if (user1.getUser().getIdUsuario() != -1 && user1.getPermisosMap().get(CREAR + entity.getClass().getSimpleName()) == null) {
            log.error("{}: No tiene permisos para la acción: {} un elemento de {} [PERMISO:{}]", new Object[]{nombreMetodo, CREAR, entity.getClass().getSimpleName(), "crear" + entity.getClass().getSimpleName()});
            throw new ApliException(TipoMensajeError.USER_NO_AUTORIZADO);
        }
        /**
         * recupera método para nuevo código
         */
        Method metodo = null;
        Class c = getIdType(entity.getClass());
        if (c.equals(Integer.class) || c.equals(Short.class) || c.equals(Byte.class) || c.equals(Long.class)) {
            String campoId = getIdName(entity.getClass());
            String nomSetMetodo = "set" + campoId.substring(0, 1).toUpperCase() + campoId.substring(1);
            Method[] methods = entity.getClass().getDeclaredMethods();
            for (Method met : methods) {
                if (met.getName().equals(nomSetMetodo)) {
                    metodo = met;
                    break;
                }
            }
        }
        /**
         * FIN -- recupera método para nuevo código
         */
        try {
//            ctx.getUserTransaction().begin();
            // obtiene el nuevo código
            if (metodo != null) {
                metodo.invoke(entity, getNuevoCodigo(entity.getClass()));
            }

            Object logObj = Aplinfo.cloneObjectEjb(entity, false);

            //En el caso de que el objeto sea de tipo CexHorario
            if (entity instanceof CexHorario) {
                CexHorario objHorTemp = (CexHorario) entity;

                //Vaciar la lista de HorarioDia
                List<CexHorariosDia> listaHorDia = new ArrayList<>();
                for (CexHorariosDia cexHorDia : objHorTemp.getCexHorariosDiaList()) {
                    listaHorDia.add(cexHorDia);
                }
                objHorTemp.getCexHorariosDiaList().clear();
                //Graba encabezados
                getEntityManager().persist(entity);
                //Recorre la lista de horariosDias
                for (CexHorariosDia cexHorDiaTemp : listaHorDia) {
                    int id = getNuevoCodigo(CexHorariosDia.class).intValue();
                    cexHorDiaTemp.setCexHorario(objHorTemp);
                    cexHorDiaTemp.setChdId(id);
                    //Graba la lista horario
                    getEntityManager().persist(cexHorDiaTemp);
                }

                /**
                 * grabar Auditoría
                 */
                String descripcion = "El usuario " + user1.getNombreFull() + " creó un horario en " + entity.getClass().getName().substring(entity.getClass().getName().lastIndexOf(".") + 1);
                grabarAuditoria(CREAR_HORARIO, logObj, user1, descripcion, "", "", "", objHorTemp.getChoId());
                /**
                 * FIN -- grabar Auditoría
                 */

            }

            /////////////////////////           }
//            ctx.getUserTransaction().commit();
        } catch (Exception e) {
            // pone el código a null
            if (metodo != null) {
                Object ob = null;
                metodo.invoke(entity, ob);
            }
//            try {
//                ctx.getUserTransaction().rollback();
//            } catch (Exception e1) {
//                log.error("crear(...) {}", e1.getMessage());
//            }
            log.error("{}: {}", nombreMetodo, e);
            if (e instanceof ApliException) {
                throw e;
            }
            throw new ApliException(TipoMensajeError.ERROR_GRABAR, e);
        }
    }

    /**
     * Modifica un registro en la tabla asociada a la clase de entidad con su
     * lista anexada(EJB3).
     *
     * @param entity la entidad a crear
     * @param user el usuario que modifica la entidad
     * @throws Exception si existe un error
     */
    @Override
    public void modificarMaestroDetalle(Object entity, Object user) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + entity.getClass().getSimpleName() + "," + user.getClass().getSimpleName() + ")";
        UsuarioAdmin user1 = (UsuarioAdmin) user;
        try {
            validarUsuarioSistema(user1);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw e;
        }
        if (user1.getUser().getIdUsuario() != -1 && user1.getPermisosMap().get(MODIFICAR + entity.getClass().getSimpleName()) == null) {
            log.error("{}: No tiene permisos para la acción: {} un elemento de {} [PERMISO:{}]", new Object[]{nombreMetodo, MODIFICAR, entity.getClass().getSimpleName(), "modificar" + entity.getClass().getSimpleName()});
            throw new ApliException(TipoMensajeError.USER_NO_AUTORIZADO);
        }
        try {
            /**
             * grabar Auditoría
             */
            Object logObj = Aplinfo.cloneObjectEjb(entity, false);

            //En el caso de que el objeto sea de tipo CexHorario
            if (entity instanceof CexHorario) {
                CexHorario objHorTemp = (CexHorario) entity;

                /**
                 * grabar Auditoría
                 */
                String descripcion = "El usuario " + user1.getNombreFull() + " modifico un horario en " + entity.getClass().getName().substring(entity.getClass().getName().lastIndexOf(".") + 1);
                getEntityManager().merge(entity);
                grabarAuditoria(MODIFICAR_HORARIO, logObj, user1, descripcion, "", "", "", objHorTemp.getChoId());
                /**
                 * FIN -- grabar Auditoría
                 */

            }

        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_MODIFICAR, e);
        }
    }

    /**
     * Modifica un registro en la tabla asociada a la clase de entidad (EJB3).
     *
     * @param entity la entidad a crear
     * @param user el usuario que modifica la entidad
     * @throws Exception si existe un error
     */
    @Override
    public void cancelarTurno(Object entity, Object user, Integer ageId, String hClinica, String secuencia) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + entity.getClass().getSimpleName() + "," + user.getClass().getSimpleName() + ")";
        UsuarioAdmin user1 = (UsuarioAdmin) user;
        try {
            validarUsuarioSistema(user1);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw e;
        }
        if (user1.getUser().getIdUsuario() != -1 && user1.getPermisosMap().get("modificar" + entity.getClass().getSimpleName()) == null) {
            log.error("{}: No tiene permisos para la acción: {} un elemento de {} [PERMISO:{}]", new Object[]{nombreMetodo, "modificar", entity.getClass().getSimpleName(), "modificar" + entity.getClass().getSimpleName()});
            throw new ApliException(TipoMensajeError.USER_NO_AUTORIZADO);
        }
        try {
            String valorDocumento;
            String codigoDocumento;
            Integer idDocumento;
            String numeroDocumento;
            idDocumento = ageId;
            codigoDocumento = hClinica;

            /**
             * grabar Auditoría
             */
            CexAgenda clase = (CexAgenda) entity;
            valorDocumento = clase.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getAdmMedico().getAmeNombreFull();
            numeroDocumento = clase.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getCexEspecialidad().getCesNombre();
            Object logObj = Aplinfo.cloneObjectEjb(entity, false);
            String descripcion = "El usuario " + user1.getNombreFull() + " cancelo el turno " + secuencia + " a la historia clinica " + hClinica + " con el médico " + valorDocumento + " en la especialidad " + clase.getCexHorariosDia().getCexHorario().getCexEspecialidadMedico().getCexEspecialidad().getCesNombre();

            grabarAuditoria(CANCELAR_TURNO, logObj, user1, descripcion, numeroDocumento, codigoDocumento, valorDocumento, idDocumento);
            /**
             * FIN -- grabar Auditoría
             */
            getEntityManager().merge(entity);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_MODIFICAR, e);
        }
    }

    /**
     * Graba la auditoría en la BD.
     *
     * @param nombreAccion
     * @param logObj el objeto a persistir en formato XML
     * @param user
     * @param descripcion la descripción corta para la auditoría
     * @param codigoDocumento
     * @param numeroDocumento
     * @param valorDocumento
     * @param idDocumento
     * @throws Exception si existe un error
     */
    protected void grabarAuditoria(String nombreAccion, Object logObj, Object user, String descripcion, String numeroDocumento, String codigoDocumento, String valorDocumento, Integer idDocumento) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(...)";
        UsuarioAdmin user1 = (UsuarioAdmin) user;
        try {
            Integer nuevoCodigo = 0;
            AdmAuditoria dmpLog = new AdmAuditoria(Aplinfo.generarUUID());
//          AdmAuditoria dmpLog = new AdmAuditoria(Calendar.getInstance().getTime().getTime());
//            dmpLog.setXmlData(Aplinfo.comprimirGz(Aplinfo.getStringXMLFromObject(logObj).getBytes()));
            dmpLog.setXmlData(Aplinfo.getStringXMLFromObject(logObj));
            dmpLog.setNombreUsuario(user1.getNombreFull());
            dmpLog.setTabla(logObj.getClass().getName().substring(logObj.getClass().getName().lastIndexOf(".") + 1));
            dmpLog.setFecha(getFechaDb());
            dmpLog.setAdmUsuario(user1.getUser());
            dmpLog.setIp(user1.getIp());
            dmpLog.setHost(user1.getHost());
            dmpLog.setNombreAccion(nombreAccion);
            dmpLog.setAdmSistema(user1.getSistema());
            dmpLog.setHora(dmpLog.getFecha());
//            dmpLog.setDmpDependencia(user1.getDmpDependencia());
            dmpLog.setDescripcion(descripcion);
            dmpLog.setIdDocumento(idDocumento);
            dmpLog.setCodigoDocumento(codigoDocumento);
            dmpLog.setValorDocumento(valorDocumento);

            getEntityManager().persist(dmpLog);
        } catch (Exception e) {
            log.error("{}: {}", new Object[]{nombreMetodo, e});
            throw e;
        }
    }

    /**
     * Verifica si el usuario es válido y tiene asociado a un sistema.
     *
     * @param user1 usuario de tipo MdmqUsuario
     * @throws Exception si existe un error
     */
    protected void validarUsuarioSistema(Object user1) throws Exception {
        if (user1 == null) {
            log.info("eliminar(...) El usuario es null");
            throw new ApliException(TipoMensajeError.USER_NO_LOGIN);
        }
//        if (user1.getSistema() == null) {
//            log.info("eliminar(...) El sistema es null");
//            throw new ApliException(TipoMensajeError.SYSTEM_NULL);
//        }
    }

    @Override
    public boolean existePorCampo(Class clase, String propiedad1, Object valor1, String propiedad2, Object valor2, String propiedad3, Object valor3, String propiedad4, Object valor4) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + clase.getSimpleName() + "," + propiedad1 + "," + valor1 + "," + propiedad2 + "," + valor2 + "," + propiedad3 + "," + valor3 + "," + propiedad4 + "," + valor4 + ")";
        try {
            String sql = "SELECT COUNT(T) FROM " + clase.getSimpleName() + " T where T." + propiedad1 + " = :var1 and T." + propiedad2 + " = :var2 and T." + propiedad3 + " = :var3 and T." + propiedad4 + " = :var4";
            Long obj = (Long) getEntityManager().createQuery(sql).setParameter("var1", valor1).setParameter("var2", valor2).setParameter("var3", valor3).setParameter("var4", valor4).getSingleResult();
            log.info("{}: {} - {}", new Object[]{nombreMetodo, sql, (obj > 0)});
            return obj.intValue() > 0;
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_BUSCAR, e);
        }
    }

    @Override
    public Date getMax(Class clase, String campo, String propiedad, Object valor) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + clase.getSimpleName() + "," + propiedad + "," + valor + "," + campo + ")";
        try {
            String sql = "SELECT MAX(T." + campo + ") FROM " + clase.getSimpleName() + " T where T." + propiedad + " = :var1";
            Date obj = (Date) getEntityManager().createQuery(sql).setParameter("var1", valor).getSingleResult();
            log.debug("{}: {} - {}", new Object[]{nombreMetodo, sql, obj});
            return obj;
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_NUEVO_CODIGO, e);
        }
    }

    @Override
    public Date getFechaDb() throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        String sql = null;
        Timestamp obj = null;
        //String dbProductName = getDbProductName();
        if (getEntityManager() == null) {
            log.warn("{}: EL ADMINISTRADOR DE PERSISTENCIA NO DEFINIDO", nombreMetodo);
            throw new ApliException(TipoMensajeError.ERROR_FECHADB);
        }
        String dbProductName = "POSTGRES";
        try {
            //log.info("getFechaDb() - getor de BD establecida {}", dbProductName == null ? "NINGUNA" : dbProductName);
            Connection con = getEntityManager().unwrap(Connection.class);
            if (con != null) {
                dbProductName = con.getMetaData().getDatabaseProductName();
            }
            dbProductName = dbProductName.toUpperCase();
            log.debug("{}: Nombre de BD utilizado: ", dbProductName);
            if (dbProductName != null) {
                if (dbProductName.contains("POSTGRES")) {
                    sql = "SELECT now()";
                } else if (dbProductName.contains("MYSQL")) {
                    sql = "SELECT now()";
                } else if (dbProductName.contains("SQLSERVER")) {
                    sql = "SELECT getDate()";
                } else if (dbProductName.contains("ORACLE")) {
                    sql = "SELECT sysdate FROM dual";
                } else if (dbProductName.contains("DERBY")) {
                    sql = "SELECT CURRENT_TIMESTAMP FROM SYSIBM.SYSDUMMY1";
                }
                obj = (Timestamp) getEntityManager().createNativeQuery(sql).getSingleResult();
                log.debug("{}: {} - {}", new Object[]{nombreMetodo, sql, obj});
            }
            return new Date(obj.getTime());
        } catch (SQLException e) {
            log.error("{}: DB({}:{}) {}", new Object[]{nombreMetodo, dbProductName, sql, e});
            throw new ApliException(TipoMensajeError.ERROR_FECHADB, e);
        }
    }

    @Override
    public Date getFechaDb(String dbProductName) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + dbProductName + ")";
        String sql = null;
        try {
            if (getEntityManager() == null) {
                log.warn("{}: NO ESTABLECIDA EL ADMINISTRADOR DE PERSISTENCIA", nombreMetodo);
                throw new ApliException(TipoMensajeError.ERROR_FECHADB);
            }
            if (dbProductName.toUpperCase().contains("POSTGRES")) {
                sql = "SELECT now()";
            } else if (dbProductName.toUpperCase().contains("MYSQL")) {
                sql = "SELECT now()";
            } else if (dbProductName.toUpperCase().contains("SQLSERVER")) {
                sql = "SELECT getDate()";
            } else if (dbProductName.toUpperCase().contains("ORACLE")) {
                sql = "SELECT sysdate FROM dual";
            }
            Timestamp obj = (Timestamp) getEntityManager().createNativeQuery(sql).getSingleResult();
            log.debug("{}: {} - {}", new Object[]{nombreMetodo, sql, obj});
            return new Date(obj.getTime());
        } catch (ApliException e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_FECHADB, e);
        }
    }

    @Override
    public List<T> listarOpLogicoParamOrdenada(Class clase, String propiedad, Object valor, String propiedad1, String operadorLogico, Object valor1, String sortColumn, boolean asc) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + clase.getSimpleName() + "," + propiedad + "," + valor + "," + propiedad1 + "," + operadorLogico + "," + valor1 + "," + sortColumn + "," + asc + ")";
        try {
            String sql = "select T from " + clase.getSimpleName() + " T where T." + propiedad + " = :var1 and T." + propiedad1 + " " + operadorLogico + " :var2 ";
            if (sortColumn != null) {
                sql += " order by T." + sortColumn + (asc ? " asc" : " desc");
            }
            Query q = getEntityManager().createQuery(sql).setParameter("var1", valor).setParameter("var2", valor1);
            List objs = q.getResultList();
            log.debug("{}: {} - {}", new Object[]{nombreMetodo, sql, objs});
            return objs;
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_LISTAR, e);
        }
    }

    /**
     * Modifica una lista grabando en auditoria el usuario que fgrabo las listas
     * auditoria grabando como que se creo un turnoa La clase de entidad (EJB3).
     * <p /> Detalle:<br /> UPDATE T SET (...) = (...) WHERE ID = ... <p />
     * Modifica los atributos de UN registro de la tabla T que corresponda a la
     * clave primaria que se encuentra en la entidad. <br />
     *
     * @param clase
     * @param lista La lista a modificar.
     * @param user El usuario que modifica la entidad.
     * @throws Exception Si existe un error.
     */
    @Override
    public void grabarListas(Class clase, List lista, Object user) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + clase.getSimpleName() + "," + user.getClass().getSimpleName() + ")";
        UsuarioAdmin user1 = (UsuarioAdmin) user;
        String valorDocumento;
        String codigoDocumento;
        Integer idDocumento;
        Object logObj;
        String descripcion;
        int id;
        boolean isMerge;
        try {
            validarUsuarioSistema(user1);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw e;
        }
        if (user1.getUser().getIdUsuario() != -1 && user1.getPermisosMap().get("crear" + clase.getSimpleName()) == null) {
            log.error("{}: No tiene permisos para la acción: {} un elemento de {} [PERMISO:{}]", new Object[]{nombreMetodo, "crear", clase.getSimpleName(), "crear" + clase.getSimpleName()});
            throw new ApliException(TipoMensajeError.USER_NO_AUTORIZADO);
        }
        try {

            //En el caso de que las listas sea de tipo CexAgenda
            if (clase.equals(CexAgenda.class)) {
                for (Iterator it = lista.iterator(); it.hasNext();) {
                    CexAgenda object = (CexAgenda) it.next();
                    /**
                     * grabar Auditoría
                     */
                    logObj = Aplinfo.cloneObjectEjb(object, false);
                    descripcion = "El usuario " + user1.getNombreFull() + " modifico el objeto " + object.getCagId();
                    idDocumento = object.getCagId();
                    codigoDocumento = "";
                    valorDocumento = "";
                    grabarAuditoria(MODIFICAR_LISTAS, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    /**
                     * FIN -- grabar Auditoría
                     */
                    getEntityManager().merge(object);
                }
                return;
            }

            //En el caso de que las listas sea de tipo CexGeriatricoConsulta
            if (clase.equals(CexGeriatricoConsulta.class)) {
                for (Iterator it = lista.iterator(); it.hasNext();) {
                    isMerge = false;
                    CexGeriatricoConsulta objGerCon = (CexGeriatricoConsulta) it.next();
                    if (objGerCon.getCgcId() == null) {
                        id = getNuevoCodigo(CexGeriatricoConsulta.class).intValue();
                        objGerCon.setCgcIdUsuario(user1.getUser().getIdUsuario().intValue());
                        objGerCon.setCgcNombreUsuario(user1.getUser().getAdmMedico().getAmeNombreFull());
                        objGerCon.setCgcId(id);
                        getEntityManager().persist(objGerCon);
                    } else {
                        getEntityManager().merge(objGerCon);
                        isMerge = true;
                    }
                    logObj = Aplinfo.cloneObjectEjb(objGerCon, false);
                    idDocumento = objGerCon.getCgcId();
                    codigoDocumento = "Historia Clínica";
                    valorDocumento = objGerCon.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                    if (!isMerge) {
                        descripcion = "El usuario " + user1.getNombreFull() + " creo objeto " + objGerCon.getCgcId();
                        grabarAuditoria(CREAR_LISTA_GERIATRICO, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    } else {
                        descripcion = "El usuario " + user1.getNombreFull() + " modifico objeto " + objGerCon.getCgcId();
                        grabarAuditoria(MODIFICAR_LISTA_GERIATRICA, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    }
                }
                return;
            }

            //En el caso de que las listas sea de tipo CexRevisionOrganos
            if (clase.equals(CexRevisionOrganos.class)) {
                for (Iterator it = lista.iterator(); it.hasNext();) {
                    isMerge = false;
                    CexRevisionOrganos objRevOrg = (CexRevisionOrganos) it.next();
                    if (objRevOrg.getCroId() == null) {
                        id = getNuevoCodigo(CexRevisionOrganos.class).intValue();
                        objRevOrg.setCroId(id);
                        getEntityManager().persist(objRevOrg);
                    } else {
                        getEntityManager().merge(objRevOrg);
                        isMerge = true;
                    }
                    logObj = Aplinfo.cloneObjectEjb(objRevOrg, false);
                    idDocumento = objRevOrg.getCroId();
                    codigoDocumento = "Historia Clínica";
                    valorDocumento = objRevOrg.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                    if (!isMerge) {
                        descripcion = "El usuario " + user1.getNombreFull() + " creo objeto " + objRevOrg.getCroId();
                        grabarAuditoria(CREAR_LISTA_REVISION_ORGANOS, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    } else {
                        descripcion = "El usuario " + user1.getNombreFull() + " modifico objeto " + objRevOrg.getCroId();
                        grabarAuditoria(MODIFICAR_LISTA_REVISION_ORGANOS, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    }
                }
                return;
            }

            //En el caso de que las listas sea de tipo CexAntecedentesPatologicos
            if (clase.equals(CexAntecedentesPatologicos.class)) {
                for (Iterator it = lista.iterator(); it.hasNext();) {
                    isMerge = false;
                    CexAntecedentesPatologicos objAntPat = (CexAntecedentesPatologicos) it.next();
                    if (objAntPat.getCapId() == null) {
                        id = getNuevoCodigo(CexAntecedentesPatologicos.class).intValue();
                        objAntPat.setCapId(id);
                        getEntityManager().persist(objAntPat);
                    } else {
                        getEntityManager().merge(objAntPat);
                        isMerge = true;
                    }
                    logObj = Aplinfo.cloneObjectEjb(objAntPat, false);
                    idDocumento = objAntPat.getCapId();
                    codigoDocumento = "Historia Clínica";
                    valorDocumento = objAntPat.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                    if (!isMerge) {
                        descripcion = "El usuario " + user1.getNombreFull() + " creo objeto " + objAntPat.getCapId();
                        grabarAuditoria(CREAR_LISTA_ANTECEDENTES_PERSONALES, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    } else {
                        descripcion = "El usuario " + user1.getNombreFull() + " modifico objeto " + objAntPat.getCapId();
                        grabarAuditoria(MODIFICAR_LISTA_ANTECEDENTES_PERSONALES, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    }
                }
                return;
            }

            //En el caso de que las listas sea de tipo CexAntecedentesFamiliares
            if (clase.equals(CexAntecedentesFamiliares.class)) {
                for (Iterator it = lista.iterator(); it.hasNext();) {
                    isMerge = false;
                    CexAntecedentesFamiliares objAntFam = (CexAntecedentesFamiliares) it.next();
                    if (objAntFam.getCafId() == null) {
                        id = getNuevoCodigo(CexAntecedentesFamiliares.class).intValue();
                        objAntFam.setCafId(id);
                        getEntityManager().persist(objAntFam);
                    } else {
                        getEntityManager().merge(objAntFam);
                        isMerge = true;
                    }
                    logObj = Aplinfo.cloneObjectEjb(objAntFam, false);
                    idDocumento = objAntFam.getCafId();
                    codigoDocumento = "Historia Clínica";
                    valorDocumento = objAntFam.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                    if (!isMerge) {
                        descripcion = "El usuario " + user1.getNombreFull() + " creo objeto " + objAntFam.getCafId();
                        grabarAuditoria(CREAR_LISTA_ANTECEDENTES_FAMILIARES, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    } else {
                        descripcion = "El usuario " + user1.getNombreFull() + " modifico objeto " + objAntFam.getCafId();
                        grabarAuditoria(MODIFICAR_LISTA_ANTECEDENTES_FAMILIARES, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    }
                }
                return;
            }

            //En el caso de que las listas sea de tipo CexExamenFisico
            if (clase.equals(CexExamenFisico.class)) {
                for (Iterator it = lista.iterator(); it.hasNext();) {
                    isMerge = false;
                    CexExamenFisico objExaFis = (CexExamenFisico) it.next();
                    if (objExaFis.getCfcId() == null) {
                        id = getNuevoCodigo(CexExamenFisico.class).intValue();
                        objExaFis.setCfcId(id);
                        getEntityManager().persist(objExaFis);
                    } else {
                        getEntityManager().merge(objExaFis);
                        isMerge = true;
                    }
                    logObj = Aplinfo.cloneObjectEjb(objExaFis, false);
                    idDocumento = objExaFis.getCfcId();
                    codigoDocumento = "Historia Clínica";
                    valorDocumento = objExaFis.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                    if (!isMerge) {
                        descripcion = "El usuario " + user1.getNombreFull() + " creo objeto " + objExaFis.getCfcId();
                        grabarAuditoria(CREAR_LISTA_FISICO_REGIONAL, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    } else {
                        descripcion = "El usuario " + user1.getNombreFull() + " modifico objeto " + objExaFis.getCfcId();
                        grabarAuditoria(MODIFICAR_LISTA_FISICO_REGIONAL, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    }
                }
                return;
            }

            //En el caso de que las listas sea de tipo CexConsultaDiagnostico
            if (clase.equals(CexDiagnosticoConsulta.class)) {
                for (Iterator it = lista.iterator(); it.hasNext();) {
                    isMerge = false;
                    CexDiagnosticoConsulta objConDia = (CexDiagnosticoConsulta) it.next();
                    if (objConDia.getDicId() == null) {
                        id = getNuevoCodigo(CexDiagnosticoConsulta.class).intValue();
                        objConDia.setDicId(id);
                        getEntityManager().persist(objConDia);
                    } else {
                        getEntityManager().merge(objConDia);
                        isMerge = true;
                    }
                    logObj = Aplinfo.cloneObjectEjb(objConDia, false);
                    idDocumento = objConDia.getDicId();
                    codigoDocumento = "Historia Clínica";
                    valorDocumento = objConDia.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                    if (!isMerge) {
                        descripcion = "El usuario " + user1.getNombreFull() + " creo objeto " + objConDia.getDicId();
                        grabarAuditoria(CREAR_LISTA_DIAGNOSTICO, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    } else {
                        descripcion = "El usuario " + user1.getNombreFull() + " modifico objeto " + objConDia.getDicId();
                        grabarAuditoria(MODIFICAR_LISTA_DIAGNOSTICO, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    }
                }
                return;
            }

            //En el caso de que las listas sea de tipo CexConsultaDiagnostico
            if (clase.equals(CexTratamientoConsulta.class)) {
                for (Iterator it = lista.iterator(); it.hasNext();) {
                    isMerge = false;
                    CexTratamientoConsulta objConTra = (CexTratamientoConsulta) it.next();
                    if (objConTra.getCptId() == null) {
                        id = getNuevoCodigo(CexTratamientoConsulta.class).intValue();
                        objConTra.setCptId(id);
                        getEntityManager().persist(objConTra);
                    } else {
                        getEntityManager().merge(objConTra);
                        isMerge = true;
                    }
                    logObj = Aplinfo.cloneObjectEjb(objConTra, false);
                    idDocumento = objConTra.getCptId();
                    codigoDocumento = "Historia Clínica";
                    valorDocumento = objConTra.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                    if (!isMerge) {
                        descripcion = "El usuario " + user1.getNombreFull() + " creo objeto " + objConTra.getCptId();
                        grabarAuditoria(CREAR_LISTA_CONSULTA_TRATAMIENTO, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    } else {
                        descripcion = "El usuario " + user1.getNombreFull() + " modifico objeto " + objConTra.getCptId();
                        grabarAuditoria(MODIFICAR_LISTA_CONSULTA_TRATAMIENTO, logObj, user1, descripcion, "", codigoDocumento, valorDocumento, idDocumento);
                    }
                }
            }

        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_MODIFICAR, e);
        }
    }

    /**
     * Crea un registro en la tabla asociada a la clase de entidad (EJB3).
     *
     * @param entity la entidad a crear
     * @param user el usuario que crea la entidad
     * @throws Exception si existe un error
     */
    @Override
    public void crearTransaccion(Object entity, Object user) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + entity.getClass().getSimpleName() + "," + user.getClass().getSimpleName() + ")";
        UsuarioAdmin user1 = (UsuarioAdmin) user;
        try {
            validarUsuarioSistema(user1);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw e;
        }
        if (user1.getUser().getIdUsuario() != -1 && user1.getPermisosMap().get(CREAR + entity.getClass().getSimpleName()) == null) {
            log.error("{}: No tiene permisos para la acción: {} un elemento de {} [PERMISO:{}]", new Object[]{nombreMetodo, CREAR, entity.getClass().getSimpleName(), "crear" + entity.getClass().getSimpleName()});
            throw new ApliException(TipoMensajeError.USER_NO_AUTORIZADO);
        }
        /**
         * recupera método para nuevo código
         */
        Method metodo = null;
        Class c = getIdType(entity.getClass());
        if (c.equals(Integer.class) || c.equals(Short.class) || c.equals(Byte.class) || c.equals(Long.class)) {
            String campoId = getIdName(entity.getClass());
            String nomSetMetodo = "set" + campoId.substring(0, 1).toUpperCase() + campoId.substring(1);
            Method[] methods = entity.getClass().getDeclaredMethods();
            for (Method met : methods) {
                if (met.getName().equals(nomSetMetodo)) {
                    metodo = met;
                    break;
                }
            }
        }
        /**
         * FIN -- recupera método para nuevo código
         */
        try {
//            ctx.getUserTransaction().begin();
            // obtiene el nuevo código
            if (metodo != null) {
                metodo.invoke(entity, getNuevoCodigo(entity.getClass()));
            }
            /**
             * grabar Auditoría
             */
            /**
             * grabar Auditoría
             */
            String valorDocumento;
            String codigoDocumento;
            Integer idDocumento;
            String numeroDocumento;

            //En el caso de ser de tipo cexConsulta
            if (entity instanceof CexConsulta) {
                CexConsulta clase = (CexConsulta) entity;
                Object logObj = Aplinfo.cloneObjectEjb(entity, false);
                String descripcion = "El usuario " + user1.getNombreFull() + " creo la consulta " + clase.getCcoId() + " a la historia clinica " + clase.getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica() + "";
                idDocumento = clase.getCcoId();
                codigoDocumento = clase.getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                numeroDocumento = "Codigo_consulta";
                valorDocumento = "Historia Clinia";
                grabarAuditoria(CREAR_CONSULTA, logObj, user1, descripcion, numeroDocumento, codigoDocumento, valorDocumento, idDocumento);
                /**
                 * FIN -- grabar Auditoría
                 */
                getEntityManager().persist(entity);
            }

            //            ctx.getUserTransaction().commit();
        } catch (Exception e) {
            // pone el código a null
            if (metodo != null) {
                Object ob = null;
                metodo.invoke(entity, ob);
            }
//            try {
//                ctx.getUserTransaction().rollback();
//            } catch (Exception e1) {
//                log.error("crear(...) {}", e1.getMessage());
//            }
            log.error("{}: {}", nombreMetodo, e);
            if (e instanceof ApliException) {
                throw e;
            }
            throw new ApliException(TipoMensajeError.ERROR_GRABAR, e);
        }
    }

    /**
     * Modifica un registro en la tabla asociada a la clase de entidad (EJB3).
     *
     * @param entity la entidad a crear
     * @param user el usuario que modifica la entidad
     * @throws Exception si existe un error
     */
    @Override
    public void modificarTransaccion(Object entity, Object user) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "(" + entity.getClass().getSimpleName() + "," + user.getClass().getSimpleName() + ")";
        UsuarioAdmin user1 = (UsuarioAdmin) user;
        try {
            validarUsuarioSistema(user1);
        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw e;
        }
        if (user1.getUser().getIdUsuario() != -1 && user1.getPermisosMap().get(MODIFICAR + entity.getClass().getSimpleName()) == null) {
            log.error("{}: No tiene permisos para la acción: {} un elemento de {} [PERMISO:{}]", new Object[]{nombreMetodo, MODIFICAR, entity.getClass().getSimpleName(), "modificar" + entity.getClass().getSimpleName()});
            throw new ApliException(TipoMensajeError.USER_NO_AUTORIZADO);
        }
        try {
            /**
             * grabar Auditoría
             */
            String valorDocumento;
            String codigoDocumento;
            Integer idDocumento;
            String numeroDocumento;
            //En el caso de ser de tipo cexConsulta
            if (entity instanceof CexConsulta) {
                CexConsulta clase = (CexConsulta) entity;
                Object logObj = Aplinfo.cloneObjectEjb(entity, false);
                String descripcion = "El usuario " + user1.getNombreFull() + " modifico consulta " + clase.getCcoId() + " a la historia clinica " + clase.getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica() + "";
                idDocumento = clase.getCcoId();
                codigoDocumento = clase.getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                numeroDocumento = "Codigo_consulta";
                valorDocumento = "Historia Clinia";
                grabarAuditoria(MODIFICAR_CONSULTA, logObj, user1, descripcion, numeroDocumento, codigoDocumento, valorDocumento, idDocumento);
                /**
                 * FIN -- grabar Auditoría
                 */
                getEntityManager().merge(entity);
            }

            //En el caso de ser de tipo cexConsulta
            if (entity instanceof CexConsultaTerapia) {
                CexConsultaTerapia clase = (CexConsultaTerapia) entity;
                Object logObj = Aplinfo.cloneObjectEjb(entity, false);
                /**
                 * grabar Auditoría
                 */
                String descripcion = "El usuario " + user1.getNombreFull() + " creo la terapia " + clase.getCctId() + " a la historia clinica " + clase.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica() + "";
                idDocumento = clase.getCctId();
                codigoDocumento = clase.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                numeroDocumento = clase.getCexTipoTerapia().getCttId().toString();
                valorDocumento = clase.getCexTipoTerapia().getCttNombre();
                grabarAuditoria(CREAR_CONSULTA_TERAPIA, logObj, user1, descripcion, numeroDocumento, codigoDocumento, valorDocumento, idDocumento);
                /**
                 * FIN -- grabar Auditoría
                 */
                getEntityManager().merge(entity);
            }

            //En el caso de ser de tipo cexPedidoLaboratorio
            if (entity instanceof CexPedidoLaboratorio) {
                CexPedidoLaboratorio clase = (CexPedidoLaboratorio) entity;
                Object logObj = Aplinfo.cloneObjectEjb(entity, false);
                /**
                 * grabar Auditoría
                 */
                String descripcion = "El usuario " + user1.getNombreFull() + " creo pedido de laboratorio " + clase.getCplId();
                idDocumento = clase.getCplId();
                if (clase.getAdmPersona() != null) {
                    codigoDocumento = clase.getAdmPersona().getAprCedula();
                } else {
                    codigoDocumento = "Cedula persona";
                }
                if (clase.getCexConsulta() != null) {
                    numeroDocumento = clase.getCexConsulta().getCexPreparacion().getCexAgenda().getCexHistoriaClinica().getChcHistoriaClinica();
                    valorDocumento = clase.getCexConsulta().getCcoId().toString();
                } else {
                    numeroDocumento = "Historia clinica";
                    valorDocumento = "Codigo consulta";
                }

                grabarAuditoria(CREAR_PEDIDO_LABORATORIO, logObj, user1, descripcion, numeroDocumento, codigoDocumento, valorDocumento, idDocumento);
                /**
                 * FIN -- grabar Auditoría
                 */
                getEntityManager().merge(entity);
            }

        } catch (Exception e) {
            log.error("{}: {}", nombreMetodo, e);
            throw new ApliException(TipoMensajeError.ERROR_MODIFICAR, e);
        }
    }

    //SECCION REPORTES
    /**
     * Genera el reporte de
     *
     * @param objeto, un objeto, por lo general en estos reporte es la
     * AdmEmpresa que da el servicio de seguridad
     * @param nombreReporte Nombre jasper
     * @param valorTipoReporte pdf o excel
     * @param nombreArchivo
     * @return
     */
    @Override
    public String generarReporteStandar(Object objeto, String nombreReporte, String valorTipoReporte, String nombreArchivo) throws Exception {
        ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";

        path = extContext.getRealPath("/");     //path de ubicacion fisica de los reportes jasper

        ParametrosReporte parametrosReporte = new ParametrosReporte();
        parametrosReporte.setName(nombreReporte);
        parametrosReporte.setLocation("/reportes/");
        Map<String, Object> parametros = new HashMap<>();

        //llenado de parametros que necesita el reporte       
        parametros.put("OBJETO", objeto);
//        parametros.put("MODULO", objeto.getRelMateriamodulo().getCodModulo().getCodModulo());
//        parametros.put("MATERIA", objeto.getRelMateriamodulo().getCodMateria().getCodMateria());
//        parametros.put("PROFESOR", objeto.getDatPersdoce().getUsrUsuario());
//        parametros.put("USUARIO", usuario);
        parametros.put("SUBREPORT_DIR", path + "/reportes/");
        parametrosReporte.setParameters(parametros);

        try {
            this.generarReporteSinDataSource(valorTipoReporte, parametrosReporte, nombreArchivo);
        } catch (ClassNotFoundException | ServletException | IOException e) {
            log.error("generarReporteStandar(): {} ", nombreMetodo, e);
        }
        return null;
    }

    @Override
    public String generarReporteStandarExplorador(Object objeto, String nombreReporte, String valorTipoReporte, String nombreInstitucion, String nombreDepartamento) throws Exception {
        ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";

        path = extContext.getRealPath("/");     //path de ubicacion fisica de los reportes jasper

        ParametrosReporte parametrosReporte = new ParametrosReporte();
        parametrosReporte.setName(nombreReporte);
        parametrosReporte.setLocation("/reportes/");
        Map<String, Object> parametros = new HashMap<>();

        //llenado de parametros que necesita el reporte       
        parametros.put("OBJETO", objeto);
        parametros.put("NOMBRE_INSTITUCION", nombreInstitucion);
        parametros.put("NOMBRE_DEPARTAMENTO", nombreDepartamento);
        parametros.put("SUBREPORT_DIR", path + "/reportes/");
        parametrosReporte.setParameters(parametros);

        try {
            this.generarReporteSinDataSourceExplorador(valorTipoReporte, parametrosReporte);
        } catch (ClassNotFoundException | ServletException | IOException e) {
            log.error("generarReporteStandarExplorador(): {} ", nombreMetodo, e);
        }
        return null;
    }

    @Override
    public String generarReporte(List listaObjetos, String nombreReporte, String valorTipoReporte, String nombreArchivo) throws Exception {
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";
        try {
            this.generarReporte(listaObjetos, nombreReporte, valorTipoReporte, nombreArchivo, 0);
        } catch (ClassNotFoundException | ServletException | IOException e) {
            log.error("generarReporte(): {} ", nombreMetodo, e);
            //e.printStackTrace();
        }
        return null;
    }

    @Override
    public String generarReporte(List listaObjetos, String nombreReporte, String valorTipoReporte, String nombreArchivo, int parametro1) throws Exception {
        ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";

        path = extContext.getRealPath("/");     //path de ubicacion fisica de los reportes jasper
        pathImages = extContext.getRealPath("/resources/images/"); //path de ubicacion de las imagenes de los reportes jasper
        ParametrosReporte parametrosReporte = new ParametrosReporte();
        parametrosReporte.setName(nombreReporte);
        parametrosReporte.setLocation("/reportes/");
        Map<String, Object> parametros = new HashMap<>();

        //llenado de parametros que necesita el reporte       
//        parametros.put("MATEMODUDOCE", objeto);
        parametros.put("PARAMETRO1", parametro1);
        parametros.put("PATHIMAGES", pathImages);
        parametros.put("SUBREPORT_DIR", path + "/reportes/");
        parametrosReporte.setParameters(parametros);

        try {
            this.generarReporte(valorTipoReporte, parametrosReporte, listaObjetos, nombreArchivo);
        } catch (ClassNotFoundException | ServletException | IOException e) {
            log.error("generarReporte(): {} ", nombreMetodo, e);
            //e.printStackTrace();
        }
        return null;
    }

    @Override
    public String generarReporteExplorador(List listaObjetos, String nombreReporte, String valorTipoReporte) throws Exception {
        ExternalContext extContext = FacesContext.getCurrentInstance().getExternalContext();
        String nombreMetodo = Thread.currentThread().getStackTrace()[1].getMethodName() + "()";

        path = extContext.getRealPath("/");     //path de ubicacion fisica de los reportes jasper

        ParametrosReporte parametrosReporte = new ParametrosReporte();
        parametrosReporte.setName(nombreReporte);
        parametrosReporte.setLocation("/reportes/");
        Map<String, Object> parametros = new HashMap<>();

        //llenado de parametros que necesita el reporte       
//        parametros.put("MATEMODUDOCE", objeto);
//        parametros.put("USUARIO", usuario);
        parametros.put("SUBREPORT_DIR", path + "/reportes/");
        parametrosReporte.setParameters(parametros);

        try {
            this.generarReporteExplorador(valorTipoReporte, parametrosReporte, listaObjetos);
        } catch (ClassNotFoundException | ServletException | IOException e) {
            log.error("generarReporteExplorador(): {} ", nombreMetodo, e);
            //e.printStackTrace();
        }
        return null;
    }

    @Override
    public void generarReporte(String tipoReporte, ParametrosReporte parametrosReporte, List listado, String nombreArchivo) throws Exception {
        String nombreReporte = parametrosReporte.getLocation() + parametrosReporte.getName();
        InputStream inputStream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream(nombreReporte);
        Connection conn = null;
        OutputStream os = null;
        JRBeanCollectionDataSource dataSource;      //es la fuente de datos o lista de entitdades a pasar

        if (inputStream == null) {
            throw new ClassNotFoundException("El Reporte no se encontró:" + nombreReporte);
        }
        FacesContext fcontext = FacesContext.getCurrentInstance();
        JRExporter exporter = null;
        try {
            InitialContext context = new InitialContext();
            ds = (DataSource) context.lookup("jdbc/HaiamDS");
            conn = ds.getConnection();
            HttpServletResponse response = (HttpServletResponse) fcontext.getExternalContext().getResponse();
            HttpServletRequest request = (HttpServletRequest) fcontext.getExternalContext().getRequest();

            parametrosReporte.getParameters().put("CONEXION", conn);

            JasperPrint jasperPrint = null;

            dataSource = new JRBeanCollectionDataSource(listado);
            jasperPrint = JasperFillManager.fillReport(inputStream, parametrosReporte.getParameters(), dataSource);
            response.setContentType(tipoReporte);
            os = response.getOutputStream();

            if (null != tipoReporte) {
                switch (tipoReporte) {
                    case "application/pdf":
                        exporter = new JRPdfExporter();
                        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        exporter.setParameter(JRPdfExporterParameter.PERMISSIONS, PdfWriter.ALLOW_PRINTING);
                        response.setHeader("Content-disposition", "attachment; filename=\"" + nombreArchivo + ".pdf");
                        break;
                    case "application/vnd.ms-excel":
                        exporter = new JRXlsExporter();
                        exporter.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
                        exporter.setParameter(JRXlsExporterParameter.IS_IGNORE_CELL_BORDER, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_FONT_SIZE_FIX_ENABLED, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_IMAGE_BORDER_FIX_ENABLED, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS, Boolean.TRUE);
                        exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
                        exporter.setParameter(JRXlsExporterParameter.MAXIMUM_ROWS_PER_SHEET, 0);
                        response.setHeader("Content-Disposition", "attachment; filename=\"" + nombreArchivo + ".xls\";");
                        System.out.println("exportando a excel:");
                        break;
                    case "text/html":
                        exporter = new JRHtmlExporter();
                        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + "/image?image=");
                        break;
                }
            }

            if (exporter != null) {
                exporter.exportReport();
            }
        } catch (JRException e) {
            log.error("generarReporte() {} ", e.getMessage());

        } catch (SQLException | IOException e) {
            log.error("generarReporte() {} ", e.getMessage());
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                log.error("generarReporte() {} ", e.getMessage());
            }
            if (os != null) {
                os.flush();
                os.close();
            }
        }

        fcontext.responseComplete();
    }

    @Override
    public void generarReporteExplorador(String tipoReporte, ParametrosReporte parametrosReporte, List listado) throws Exception {
        String nombreReporte = parametrosReporte.getLocation() + parametrosReporte.getName();
        InputStream inputStream = FacesContext.getCurrentInstance().getExternalContext()
                .getResourceAsStream(nombreReporte);
        Connection conn = null;
        OutputStream os = null;
        JRBeanCollectionDataSource dataSource;      //es la fuente de datos o lista de entitdades a pasar

        if (inputStream == null) {
            throw new ClassNotFoundException("El Reporte no se encontró:" + nombreReporte);
        }
        FacesContext fcontext = FacesContext.getCurrentInstance();
        JRExporter exporter = null;
        try {
            InitialContext context = new InitialContext();
            ds = (DataSource) context.lookup("jdbc/HaiamDS");
            conn = ds.getConnection();
            HttpServletResponse response = (HttpServletResponse) fcontext.getExternalContext().getResponse();
            HttpServletRequest request = (HttpServletRequest) fcontext.getExternalContext().getRequest();

            parametrosReporte.getParameters().put("CONEXION", conn);

            JasperPrint jasperPrint = null;

            dataSource = new JRBeanCollectionDataSource(listado);
            jasperPrint = JasperFillManager.fillReport(inputStream, parametrosReporte.getParameters(), dataSource);
            response.setContentType(tipoReporte);
            os = response.getOutputStream();

            if ("application/pdf".equals(tipoReporte)) {
                exporter = new JRPdfExporter();
                exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                exporter.setParameter(JRPdfExporterParameter.PERMISSIONS, PdfWriter.ALLOW_PRINTING);
                //response.setHeader("Content-disposition", "attachment; filename=\""+nombreArchivo+".pdf");                        

            }

            if (exporter != null) {
                exporter.exportReport();
            }
        } catch (JRException e) {
            log.error("generarReporteExplorador() {} ", e.getMessage());

        } catch (SQLException | IOException e) {
            log.error("generarReporteExplorador() {} ", e.getMessage());
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                log.error("generarReporteExplorador() {} ", e.getMessage());
            }
            if (os != null) {
                os.flush();
                os.close();
            }
        }

        fcontext.responseComplete();
    }

    @Override
    public void generarReporteSinDataSource(String tipoReporte, ParametrosReporte parametrosReporte, String nombreArchivo) throws Exception {
        String nombreReporte = parametrosReporte.getLocation() + parametrosReporte.getName();
        InputStream inputStream = FacesContext.getCurrentInstance().getExternalContext()
                .getResourceAsStream(nombreReporte);
        Connection conn = null;
        OutputStream os = null;
        String realPath = null;

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        if (inputStream == null) {
            throw new ClassNotFoundException("El Reporte no se encontrÃ³:" + nombreReporte);
        }
        FacesContext fcontext = FacesContext.getCurrentInstance();

        try {
            InitialContext context = new InitialContext();
            ds = (DataSource) context.lookup("jdbc/HaiamDS");
            conn = ds.getConnection();
            HttpServletResponse response = (HttpServletResponse) fcontext.getExternalContext().getResponse();
            HttpServletRequest request = (HttpServletRequest) fcontext.getExternalContext().getRequest();

            JRExporter exporter = null;

            ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();//  fcontext.getExternalContext().getContext();

            realPath = servletContext.getRealPath("/reportes/");
            System.out.println("otros paths:" + realPath);
//                File fileFeport = new File(realPath+parametrosReporte.getLocation());
            //parametrosReporte.getParameters().put(JRParameter.REPORT_FILE_RESOLVER, new SimpleFileResolver(fileFeport));
//                parametrosReporte.getParameters().put("RPT_USUARIO", usuario.getFullNombre());

            JasperPrint jasperPrint = null;

            jasperPrint = JasperFillManager.fillReport(inputStream, parametrosReporte.getParameters(), conn);
            response.setContentType(tipoReporte);
            os = response.getOutputStream();

            if (null != tipoReporte) {
                switch (tipoReporte) {
                    case "application/pdf":
                        exporter = new JRPdfExporter();
                        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        response.setHeader("Content-Disposition", "attachment; filename=\"" + nombreArchivo + "\";");
                        break;
                    case "application/vnd.ms-excel":
                        exporter = new JRXlsExporter();
                        //exporter = new JRXlsxExporter();
                        exporter.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
                        exporter.setParameter(JRXlsExporterParameter.IS_IGNORE_CELL_BORDER, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_FONT_SIZE_FIX_ENABLED, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_IMAGE_BORDER_FIX_ENABLED, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS, Boolean.TRUE);
                        exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
                        exporter.setParameter(JRXlsExporterParameter.MAXIMUM_ROWS_PER_SHEET, 0);
                        response.setHeader("Content-Disposition", "attachment; filename=\"" + nombreArchivo + "\";");
                        System.out.println("exportando a excel:");
                        break;
                    case "text/html":
                        exporter = new JRHtmlExporter();
                        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);
                        exporter.setParameter(JRHtmlExporterParameter.IS_OUTPUT_IMAGES_TO_DIR, Boolean.TRUE);
                        exporter.setParameter(JRHtmlExporterParameter.ZOOM_RATIO, (float) 1.5);
                        exporter.setParameter(JRHtmlExporterParameter.IMAGES_DIR_NAME, realPath + "/resources/images/");
                        exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "images?image=");
                        break;
                    case "application/msword":
                        exporter = new JRRtfExporter();
                        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        exporter.setParameter(JRExporterParameter.IGNORE_PAGE_MARGINS, true);
                        break;
                }
            }

            if (exporter != null) {
                exporter.exportReport();

            }

        } catch (JRException e) {
            log.error("generarReporteSinDataSource() {} ", e.getMessage());
        } catch (SQLException | IOException e) {
            log.error("generarReporteSinDataSource() {} ", e.getMessage());
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                log.error("generarReporteSinDataSource() {} ", e.getMessage());
            }
            if (os != null) {
                os.flush();
                os.close();
            }

        }

        fcontext.responseComplete();

    }

    @Override
    public void generarReporteSinDataSourceExplorador(String tipoReporte, ParametrosReporte parametrosReporte) throws Exception {
        String nombreReporte = parametrosReporte.getLocation() + parametrosReporte.getName();
        InputStream inputStream = FacesContext.getCurrentInstance().getExternalContext()
                .getResourceAsStream(nombreReporte);
        Connection conn = null;
        OutputStream os = null;
        String realPath = null;

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        if (inputStream == null) {
            throw new ClassNotFoundException("El Reporte no se encontrÃ³:" + nombreReporte);
        }
        FacesContext fcontext = FacesContext.getCurrentInstance();

        try {
            InitialContext context = new InitialContext();
            ds = (DataSource) context.lookup("jdbc/HaiamDS");
            conn = ds.getConnection();
            HttpServletResponse response = (HttpServletResponse) fcontext.getExternalContext().getResponse();
            HttpServletRequest request = (HttpServletRequest) fcontext.getExternalContext().getRequest();

            JRExporter exporter = null;

            ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();//  fcontext.getExternalContext().getContext();

            realPath = servletContext.getRealPath("/reportes/");
            System.out.println("otros paths:" + realPath);
//                File fileFeport = new File(realPath+parametrosReporte.getLocation());
            //parametrosReporte.getParameters().put(JRParameter.REPORT_FILE_RESOLVER, new SimpleFileResolver(fileFeport));
//                parametrosReporte.getParameters().put("RPT_USUARIO", usuario.getFullNombre());

            JasperPrint jasperPrint = null;

            jasperPrint = JasperFillManager.fillReport(inputStream, parametrosReporte.getParameters(), conn);
            response.setContentType(tipoReporte);
            os = response.getOutputStream();

            if ("application/pdf".equals(tipoReporte)) {

                exporter = new JRPdfExporter();
                exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                //response.setHeader("Content-Disposition","attachment; filename=\""+nombreArchivo+"\";");
            }

            if (exporter != null) {
                exporter.exportReport();

            }

        } catch (JRException e) {
            log.error("generarReporteSinDataSourceExplorador() {} ", e.getMessage());
        } catch (SQLException | IOException e) {
            log.error("generarReporteSinDataSourceExplorador() {} ", e.getMessage());
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                log.error("generarReporteSinDataSourceExplorador() {} ", e.getMessage());
            }
            if (os != null) {
                os.flush();
                os.close();
            }

        }

        fcontext.responseComplete();
    }

    @Override
    public void generarReporteSinDataSourceXlsx(String tipoReporte, ParametrosReporte parametrosReporte, String nombreArchivo) throws Exception {
        String nombreReporte = parametrosReporte.getLocation() + parametrosReporte.getName();
        InputStream inputStream = FacesContext.getCurrentInstance().getExternalContext()
                .getResourceAsStream(nombreReporte);
        Connection conn = null;
        OutputStream os = null;
        String realPath = null;
        HttpServletResponse response = null;

        if (inputStream == null) {
            throw new ClassNotFoundException("El Reporte no se encontró:" + nombreReporte);
        }
        FacesContext fcontext = FacesContext.getCurrentInstance();

        try {
            InitialContext context = new InitialContext();
            ds = (DataSource) context.lookup("jdbc/HaiamDS");
            conn = ds.getConnection();
            response = (HttpServletResponse) fcontext.getExternalContext().getResponse();
            HttpServletRequest request = (HttpServletRequest) fcontext.getExternalContext().getRequest();

            JRExporter exporter = null;

            ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();//  fcontext.getExternalContext().getContext();

            realPath = servletContext.getRealPath("/reportes/");
            System.out.println("otro path:" + realPath);
            File fileFeport = new File(realPath + parametrosReporte.getLocation());
            //parametrosReporte.getParameters().put(JRParameter.REPORT_FILE_RESOLVER, new SimpleFileResolver(fileFeport));
//                parametrosReporte.getParameters().put("RPT_USUARIO", usuario.getFullNombre());               

            JasperPrint jasperPrint = null;

            jasperPrint = JasperFillManager.fillReport(inputStream, parametrosReporte.getParameters(), conn);
            response.setContentType(tipoReporte);
            os = response.getOutputStream();

            if (null != tipoReporte) {
                switch (tipoReporte) {
                    case "application/pdf":
                        exporter = new JRPdfExporter();
                        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        response.setHeader("Content-Disposition", "attachment; filename=\"" + nombreArchivo + "\";");
                        break;
                    case "application/vnd.ms-excel":
                        //exporter = new JRXlsxExporter();
                        exporter = new JRXlsExporter();
                        exporter.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.TRUE);
                        exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
                        exporter.setParameter(JRXlsExporterParameter.IS_IGNORE_CELL_BORDER, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_FONT_SIZE_FIX_ENABLED, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_IMAGE_BORDER_FIX_ENABLED, Boolean.FALSE);
                        exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS, Boolean.TRUE);
                        exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
                        response.setHeader("Content-Disposition", "attachment; filename=\"" + nombreArchivo + "\";");
                        System.out.println("exportando a excel:");
                        break;
                    case "text/html":
                        exporter = new JRHtmlExporter();
                        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath() + "/image?image=");
                        break;
                    case "application/msword":
                        exporter = new JRRtfExporter();
                        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
                        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);
                        exporter.setParameter(JRExporterParameter.IGNORE_PAGE_MARGINS, true);
                        break;
                }
            }

            if (exporter != null) {
                exporter.exportReport();

            }

        } catch (JRException e) {
            log.error("generarReporteSinDataSourceXlsx() {} ", e.getMessage());
        } catch (SQLException | IOException e) {
            log.error("generarReporteSinDataSourceXlsx() {} ", e.getMessage());
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                log.error("generarReporteSinDataSourceXlsx() {} ", e.getMessage());
            }
            if (os != null) {
                os.flush();
                os.close();
            }

        }

        fcontext.responseComplete();
    }

    @Override
    public void generarReporteSinDataSourceXls(String tipoReporte, ParametrosReporte parametrosReporte) throws Exception {
        String nombreReporte = parametrosReporte.getLocation() + parametrosReporte.getName();
        InputStream inputStream = FacesContext.getCurrentInstance().getExternalContext()
                .getResourceAsStream(nombreReporte);
        Connection conn = null;
        //OutputStream osxls = null;
        String realPath = null;
        HttpServletResponse response = null;
        //JRXlsExporter exporterXls = null;

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        OutputStream osxls = null;

        if (inputStream == null) {
            throw new ClassNotFoundException("El Reporte no se encontró:" + nombreReporte);
        }
        FacesContext fcontext = FacesContext.getCurrentInstance();

        try {
            InitialContext context = new InitialContext();
            ds = (DataSource) context.lookup("jdbc/HaiamDS");
            conn = ds.getConnection();
            response = (HttpServletResponse) fcontext.getExternalContext().getResponse();
            HttpServletRequest request = (HttpServletRequest) fcontext.getExternalContext().getRequest();

            JExcelApiExporter exporterXls = new JExcelApiExporter();

            ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();//  fcontext.getExternalContext().getContext();

            realPath = servletContext.getRealPath("/reporte/");
            System.out.println("otro path:" + realPath);

            //File fileFeport = new File(realPath+parametrosReporte.getLocation());
            //parametrosReporte.getParameters().put(JRParameter.REPORT_FILE_RESOLVER, new SimpleFileResolver(fileFeport));
//                parametrosReporte.getParameters().put("RPT_USUARIO", usuario.getFullNombre());                
            JasperPrint jasperPrint = null;

            jasperPrint = JasperFillManager.fillReport(inputStream, parametrosReporte.getParameters(), conn);
            response.setContentType(tipoReporte);
            //exporterXls = new JRXlsExporter();
            //osxls = response.getOutputStream();
            osxls = new FileOutputStream(new File(realPath + "/genreport.xls"));
            exporterXls.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);
            exporterXls.setParameter(JRExporterParameter.OUTPUT_STREAM, byteArrayOutputStream);
            //exporterXls.setParameter(JRExporterParameter.OUTPUT_FILE_NAME,"/reporte.xls");
            exporterXls.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.TRUE);

            exporterXls.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
            exporterXls.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
            exporterXls.setParameter(JRXlsExporterParameter.IS_IGNORE_CELL_BORDER, Boolean.FALSE);
            exporterXls.setParameter(JRXlsExporterParameter.IS_FONT_SIZE_FIX_ENABLED, Boolean.TRUE);
            exporterXls.setParameter(JRXlsExporterParameter.IS_IMAGE_BORDER_FIX_ENABLED, Boolean.FALSE);
            exporterXls.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS, Boolean.TRUE);
            exporterXls.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
            response.setHeader("Content-Disposition", "attachment; filename=\"reporte.xls\";");
            System.out.println("exportando a excels:");

            exporterXls.exportReport();

        } catch (JRException e) {
            log.error("generarReporteSinDataSourceXls() {} ", e.getMessage());
        } catch (SQLException | FileNotFoundException e) {
            log.error("generarReporteSinDataSourceXls() {} ", e.getMessage());
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                log.error("generarReporteSinDataSourceXls() {} ", e.getMessage());
            }

            osxls.write(byteArrayOutputStream.toByteArray());
            osxls.flush();
            osxls.close();
            System.out.println("escribiendo a excels:");

        }

//                File file = new File(realPath+"/genreport.xls");
//                FileInputStream is = new FileInputStream(file);
//                ServletOutputStream outaux = response.getOutputStream();
//                int length = (int) file.length();           
//                byte[] bytes = new byte[length];  
//                System.out.println("tamaño archivo:"+length);
//                if(length > 0){
//                while(is.read(bytes, 0, length) != -1)
//                      {
//                        System.out.println("archivo:"+length);
//                        outaux.write(bytes, 0, length);
//                      }       
//                }
//                        is.close();    
//                        outaux.flush();
//                        outaux.close();	
        //fcontext.responseComplete();
    }

}
